package com.corpgovernment.organization.service.impl;

import com.corpgovernment.api.costcenter.model.CostCenter;
import com.corpgovernment.api.organization.model.bookingrelation.BookingRange;
import com.corpgovernment.api.organization.model.passenger.PassengerVo;
import com.corpgovernment.common.base.BaseRequestVO.UserInfo;
import com.corpgovernment.organization.constant.CommonConst;
import com.corpgovernment.organization.entity.db.MbFreshPassenger;
import com.corpgovernment.organization.enumm.DefaultBookRangeEnum;
import com.corpgovernment.organization.service.BookingRelationService;
import com.corpgovernment.organization.vo.GetPassengerRequestVO;
import com.corpgovernment.organization.vo.GetPassengerResponseVO;
import com.corpgovernment.organization.vo.PassengerInfoVO;
import com.ctrip.corp.obt.generic.utils.CollectionUtils;
import com.ctrip.corp.obt.generic.utils.JsonUtils;
import com.ctrip.corp.obt.generic.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.corpgovernment.common.enums.SystemType.zhongjin;

/**
 * @author jhxue
 * @create 2022-02-25-14:33
 */
@Service
@Slf4j
public class PassengerPubService extends AbstractPassengerService {

	@Autowired
	private BookingRelationService bookingRelationService;

	/**
	 * 查询出行人
	 *
	 * @param request
	 * @return
	 */
	@Override
	public GetPassengerResponseVO getPassenger(GetPassengerRequestVO request) {
		try {
			initElkLog();
			addElkInfoLog("不校验出行人流程");
			UserInfo userInfo = request.getUserInfo();
			boolean showAdd = false;
			BookingRange bookingRange = bookingRelationService.queryBookingRangeByUidAndOrgId(userInfo.getUid(), userInfo.getOrgId());
			boolean bookForNonEmp = Optional.ofNullable(bookingRange).map(BookingRange::getBookForNonEmp).orElse(false);
			addElkInfoLog("该员工的代定范围：%s", JsonUtils.toJsonString(bookingRange));
			if (bookingRange != null) {
				showAdd = Optional.ofNullable(bookingRange.getBookForNonEmp()).orElse(false);
			}
			// 1.查询出行人信息
			List<PassengerVo> passengerList = this.getPassengerByPub(request, bookingRange);
			// 2.完善出行人信息
			passengerList = this.packagePassengerList(passengerList, request);
			// 3.出行人排序
			passengerList = this.sort(passengerList, userInfo);
			//完善成本中心信息
			refineCostCenterData(passengerList);
			// 4.封装返回
			return GetPassengerResponseVO.createV2(passengerList, showAdd, bookForNonEmp);
		} finally {
			log.info("PassengerService.getPassenger获取可用出行人{} request：{}{}{}{}", System.lineSeparator(), JsonUtils.toJsonString(request), System.lineSeparator(), System.lineSeparator(), this.getElkInfoLog());
			clearElkLog();
		}
	}

	/**
	 * 因公获取出行人
	 *
	 * @param requestVO
	 * @param bookingRange
	 * @return
	 */
	private List<PassengerVo> getPassengerByPub(GetPassengerRequestVO requestVO, BookingRange bookingRange) {
		List<String> bookingOrgIds = new ArrayList<>();
		List<BookingRange.BookingUser> bookingUsers = new ArrayList<>();
		boolean bookForNonEmp = false;
		String bookRangeCode = organizationApollo.getDefaultBookRange();
		addElkInfoLog("系统默认的代订范围：%s", bookRangeCode);
		DefaultBookRangeEnum bookRangeEnum = DefaultBookRangeEnum.getByCode(bookRangeCode);
		if (bookRangeEnum == DefaultBookRangeEnum.All) {
			bookingOrgIds.addAll(organizationInfoService.listAllValidOrgId());
		} else {
			if (bookingRange != null) {
				addElkInfoLog("该员工的代定范围：%s", JsonUtils.toJsonString(bookingRange));
				bookForNonEmp = bookingRange.getBookForNonEmp();
				bookingUsers = bookingRange.getBookingUsers();
                bookingOrgIds.addAll(bookingRange.getBookingRange());
			}
		}
		UserInfo userInfo = requestVO.getUserInfo();
		bookingOrgIds = bookingOrgIds.stream().distinct().collect(Collectors.toList());
		String query = requestVO.getQuery();
		String uid = userInfo.getUid();
		String orgId = userInfo.getOrgId();
		Integer page = requestVO.getPage();
		List<MbFreshPassenger> freshPassengerList = new ArrayList<>();
		if (bookForNonEmp) {
			addElkInfoLog("查询范围包括非员工");
			if (StringUtils.isBlank(query)) {
				freshPassengerList = freshPassengerLoader.pageByBookingOrgIds(bookingOrgIds, bookingUsers, uid, orgId, page, CommonConst.PAGE_SIZE_30);
			} else {
				addElkInfoLog("查询条件：%s", query);
				String systemType = organizationApollo.getSystemType();
				addElkInfoLog("系统模式：%s", systemType);
				List<Long> freshPassengerIds = new ArrayList<>();
				if (Objects.equals(zhongjin.getCode(), systemType)) {
					// 名称精确匹配或身份证号精确匹配
					freshPassengerIds = this.queryByNameOrCardNo(query, false);
				} else {
					// 名称模糊查询
					freshPassengerIds = this.queryLikeName(query, false);
				}
				addElkInfoLog("查询到的fresh id：%s", freshPassengerIds);
				if (CollectionUtils.isNotEmpty(freshPassengerIds)) {
					freshPassengerList = freshPassengerLoader.pageByBookingOrgIdsAndFreshPassengerIds(bookingOrgIds, bookingUsers, freshPassengerIds, uid, orgId, page, CommonConst.PAGE_SIZE_30);
				}
			}
		} else {
			addElkInfoLog("查询范围不包括非员工");
			String queryUid = requestVO.getUid();
			if (StringUtils.isBlank(query)) {
				addElkInfoLog("查询条件：%s", query);
				freshPassengerList = freshPassengerLoader.pageEmployeeByBookingOrgIds(bookingOrgIds, bookingUsers, queryUid, page, CommonConst.PAGE_SIZE_30, orgId);
			} else {
				String systemType = organizationApollo.getSystemType();
				addElkInfoLog("查询模式：%s", systemType);
				List<Long> freshPassengerIds = new ArrayList<>();
				if (Objects.equals(zhongjin.getCode(), systemType)) {
					// 名称精确匹配或身份证号精确匹配
					freshPassengerIds.addAll(this.queryByNameOrCardNo(query, true));
				} else {
					// 名称模糊查询
					freshPassengerIds.addAll(this.queryLikeName(query, true));
				}
				addElkInfoLog("查询到的fresh id：%s", freshPassengerIds);
				if (CollectionUtils.isNotEmpty(freshPassengerIds)) {
					freshPassengerList = freshPassengerLoader.pageEmployeeByBookingOrgIdsAndName(bookingOrgIds, bookingUsers, freshPassengerIds, queryUid, page, CommonConst.PAGE_SIZE_30, orgId);
				}
			}
		}
		addElkInfoLog("出行人信息：%s", JsonUtils.toJsonString(freshPassengerList));
		if (CollectionUtils.isEmpty(freshPassengerList)) {
			addElkInfoLog("未查到出行人，流程结束");
			return new ArrayList<>();
		}
		freshPassengerList = this.filterPassenger(freshPassengerList);
		addElkInfoLog("过滤后的出行人信息: %s",JsonUtils.toJsonString(freshPassengerList));
		//PageInfo<MbFreshPassenger> pageInfo = new PageInfo<>(freshPassengerList);
		//int totalPage = pageInfo.getPages();
		//boolean pageEnd = requestVO.getPage() == totalPage;
		List<PassengerVo> passengerList = passengerConvert.convertFromFreshPassenger(freshPassengerList, orgId);
		addElkInfoLog("转换后的出行人信息: %s",JsonUtils.toJsonString(passengerList));
		//passengerList.forEach(e -> e.setPageEnd(pageEnd));
		List<PassengerInfoVO> selectedList = requestVO.getSelectedList();
		if (CollectionUtils.isEmpty(selectedList)) {
			return passengerList;
		}
		// 将选中的员工排掉
		List<String> uidList = selectedList.stream().filter(p -> StringUtils.isNotBlank(p.getUid())).map(PassengerInfoVO::getUid).collect(Collectors.toList());
		List<String> noUidList = selectedList.stream().filter(p -> StringUtils.isNotBlank(p.getNoEmployeeId())).map(PassengerInfoVO::getNoEmployeeId).collect(Collectors.toList());
		if (Objects.isNull(requestVO.getIsExcludeSelected()) || !requestVO.getIsExcludeSelected()) {
			return passengerList.stream().filter(e -> !uidList.contains(e.getUid()) && !noUidList.contains(e.getNoEmployeeId())).collect(Collectors.toList());
		}
		return passengerList.stream().filter(e -> {
			if (StringUtils.isEmpty(e.getUid())) {
				return noUidList.contains(e.getNoEmployeeId());
			} else {
				return uidList.contains(e.getUid());
			}
		}).collect(Collectors.toList());
	}

	private List<MbFreshPassenger> 	filterPassenger(List<MbFreshPassenger> freshPassengerList) {
		List<MbFreshPassenger> list = new ArrayList<>();
		Set<String> set = new HashSet<>();
		freshPassengerList.forEach(e -> {
			String key;
			if (StringUtils.isBlank(e.getEmployeeUid())) {
				key = e.getNonEmployeeUid() + "_" + e.getOrgId();
			} else {
				key = e.getEmployeeUid() + "_" + e.getOrgId();
			}
			if (set.contains(key)) {
				return;
			}
			list.add(e);
			set.add(key);
		});
		return list;
	}

	@Override
	public String getType() {
		return "PUB";
	}

	/**
	 * 完善成本中心信息
	 */
	private void refineCostCenterData(List<PassengerVo> passengerList){
		if (CollectionUtils.isEmpty(passengerList)){
			return;
		}
		for (PassengerVo passenger : passengerList) {
			if (Objects.isNull(passenger.getCostCenter())){
				return;
			}
			CostCenter costCenter = passenger.getCostCenter();
			if (Objects.isNull(passenger.getCostCenterId())){
				passenger.setCostCenterId(costCenter.getCostCenterId());
			}
			if (Objects.isNull(passenger.getCostCenterName())){
				passenger.setCostCenterName(costCenter.getCostCenterName());
			}
			if (Objects.isNull(passenger.getCostCenterCode())){
				passenger.setCostCenterCode(costCenter.getCostCenterCode());
			}
		}
	}

}
